// 2024-11-8
fn main() {
  // 普通指针和原始指针区别
  // 1. 借用规则
  let mut v = vec![1,2,3];
  // 借用规则，不能同时存在可变和不可变借用
  let r1 = &v[0];
  println!("消费r1: {}", r1);
  // 如果是一个可变, 一个不可变, 则不可变借用的消费者必须先消费完, 才能进行可变借用
  // 后面进行可变借用
  let r2 = &mut v[0];
  println!("消费r2: {}", r2);
  // let r3 = &mut v[0];
  // println!("消费r3: {}", r3);

  // 但是, 原始指针则可以规避
  let mut v1 = vec![1,2,3];
  let rr2 = &v1[0] as *const i32;
  let rr3 = &mut v1[0] as *mut i32;

  unsafe {
    // 不可变借用竟然可以在可变借用发生之后进行消费
    println!("消费rr2: {}", *rr2);
    println!("消费rr3: {}", *rr3);
  }

  // 2. 安全抽象
  // let mut v2 = vec![1,2,3,4,5,6];
  // // 注意, 以下两种写法是不一样的
  // // a.可变切片
  // let p1 = &mut v2[..];
  // p1[6] = 3; // p1只能修改其已经存在的成员, 不能添加新的成员
  // // b.可变引用
  // let p2 = &mut v2;
  // p2.push(2); // p2可以添加新的成员

  let mut v2 = vec![1,2,3,4,5,6];
  let p = &mut v2[..];
  let (a, b) = p.split_at_mut(3);
  println!("a: {:?}, b: {:?}", a, b);
  // 原始的集合不会发生改变
  println!("v2: {:?}", v2);
  // fn split_at_mut (slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
  //   let len = slice.len();
  //   assert!(mid <= len);
  //   (&mut slice(..mid), &mut slice[mid..])
  // }
  fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
    let len = slice.len();
    assert!(mid <= len);
    let ptr = slice.as_mut_ptr();
    unsafe {
      (
        core::slice::from_raw_parts_mut(ptr, mid),
        core::slice::from_raw_parts_mut(ptr.add(mid), len-mid)
      )
    }
  }
  let mut v3 = vec![1,2,3,4,5,6];
  let arr = split_at_mut(&mut v3[..], 3);
  println!("arr: {:?}", arr);
  // 注意静态变量必须指定类型
  static mut CON:i32 = 12; // 静态变量
  unsafe {
    CON += 1;
    println!("CON: {}", CON);
  }
}